package com.fzt.admin.common.biz.user;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.fzt.admin.common.convention.exception.ClientException;
import com.google.common.collect.Lists;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

import static com.fzt.admin.common.constant.RedisCacheConstant.USER_LOGIN_KEY;
import static com.fzt.admin.common.enums.UserErrorCodeEnum.USER_TOKEN_FAIL;

/**
 * 用户信息传输过滤器
 */
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {
    private final StringRedisTemplate stringRedisTemplate;

    private final List<String> IGNORE_URI = Lists.newArrayList(
            "/api/short-link/admin/v1/user/login",
            "/api/short-link/admin/v1/user/has-username"
    );
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String requestURI = httpServletRequest.getRequestURI();
        if (!IGNORE_URI.contains(requestURI)){
            String method = httpServletRequest.getMethod();
            if (!(Objects.equals(requestURI,"/api/short-link/admin/v1/user") && Objects.equals(method, "PUT"))){
                String username = httpServletRequest.getHeader("username");
                String token = httpServletRequest.getHeader("token");
                if (!(StrUtil.isAllNotBlank(username, token))) {
                    throw new ClientException(USER_TOKEN_FAIL);
                }
                Object userInfoStr;
                try {
                    userInfoStr = stringRedisTemplate.opsForHash().get(USER_LOGIN_KEY + username, token);
                    if (userInfoStr == null) {
                        throw new ClientException(USER_TOKEN_FAIL);
                    }
                }catch (Exception ex){
                    throw new ClientException(USER_TOKEN_FAIL);
                }
                UserInfoDTO userInfoDTO = JSON.parseObject(userInfoStr.toString(), UserInfoDTO.class);
                UserContext.setUser(userInfoDTO);

                try {
                    filterChain.doFilter(servletRequest, servletResponse);
                } finally {
                    UserContext.removeUser();
                }
            }else filterChain.doFilter(servletRequest, servletResponse);
        }else filterChain.doFilter(servletRequest, servletResponse);

    }
}